from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils import timezone


class AllowedEmail(models.Model):
    """邮箱白名单模型"""
    email = models.EmailField(unique=True, max_length=100, verbose_name='Email Address')
    description = models.CharField(max_length=200, blank=True, null=True, verbose_name='Description')
    is_active = models.BooleanField(default=True, verbose_name='Permission')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Create Time')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Update Time')
    
    class Meta:
        db_table = 'allowed_emails'
        verbose_name = 'Email whitelist'
        verbose_name_plural = 'Email whitelist'
        ordering = ['-created_at']
    
    def __str__(self):
        return self.email
    
    @classmethod
    def is_email_allowed(cls, email):
        """检查邮箱是否在白名单中且启用"""
        return cls.objects.filter(email=email, is_active=True).exists()


class UserManager(BaseUserManager):
    """自定义用户管理器"""
    
    def create_user(self, email, nickname, password=None, **extra_fields):
        """创建普通用户"""
        if not email:
            raise ValueError('Users must have an email address')
        if not nickname:
            raise ValueError('Users must have a nickname')
            
        email = self.normalize_email(email)
        user = self.model(email=email, nickname=nickname, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_superuser(self, email, nickname, password=None, **extra_fields):
        """创建超级用户"""
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        
        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True')
            
        return self.create_user(email, nickname, password, **extra_fields)


class User(AbstractUser):
    """用户模型"""
    GENDER_CHOICES = [
        (0, 'Unknown'),
        (1, 'Male'),
        (2, 'Female'),
    ]
    
    user_id = models.AutoField(primary_key=True, verbose_name='User ID')
    email = models.EmailField(unique=True, max_length=100, verbose_name='Email')
    nickname = models.CharField(max_length=50, verbose_name='Nickname')
    avatar = models.URLField(
        max_length=500, 
        default='https://campus-nexus.oss-cn-guangzhou.aliyuncs.com/avatar/default/default.jpg',
        verbose_name='Avatar URL'
    )
    gender = models.IntegerField(choices=GENDER_CHOICES, default=0, verbose_name='Gender')
    signature = models.CharField(max_length=100, blank=True, null=True, verbose_name='Signature')
    institution = models.CharField(max_length=200, blank=True, null=True, verbose_name='Institution Name')  # 机构名称，外来用户有值，正常注册用户为空
    register_time = models.DateTimeField(default=timezone.now, verbose_name='Register Time')
    last_login_time = models.DateTimeField(blank=True, null=True, verbose_name='Last Login Time')

    username = None
    first_name = None
    last_name = None
    
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['nickname']
    
    objects = UserManager()
    
    class Meta:
        db_table = 'users'
        verbose_name = 'User'
        verbose_name_plural = 'Users'
        
    def __str__(self):
        return self.nickname


class Badge(models.Model):
    """成就徽章模型"""
    badge_id = models.AutoField(primary_key=True, verbose_name='Badge ID')
    name = models.CharField(max_length=100, verbose_name='Badge Name')
    description = models.CharField(max_length=500, verbose_name='Badge Description')
    img = models.CharField(max_length=500, verbose_name='Badge Image')
    create_time = models.DateTimeField(default=timezone.now, verbose_name='Create Time')
    
    class Meta:
        db_table = 'badges'
        verbose_name = 'Badge'
        verbose_name_plural = 'Badges'
        
    def __str__(self):
        return self.name


class UserBadge(models.Model):
    """用户徽章关联模型"""
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='User')
    badge = models.ForeignKey(Badge, on_delete=models.CASCADE, verbose_name='Badge')
    get_time = models.DateTimeField(default=timezone.now, verbose_name='Get Time')
    is_show = models.BooleanField(default=False, verbose_name='Is Show')
    
    class Meta:
        db_table = 'user_badges'
        verbose_name = 'User Badge'
        verbose_name_plural = 'User Badges'
        unique_together = ['user', 'badge']


class UserMessage(models.Model):
    """用户消息模型"""
    MESSAGE_TYPE_CHOICES = [
        (0, 'System Message'),
        (1, 'Reply to Post'),
        (2, 'Reply to Comment'),
        (3, 'Like Article'),
        (4, 'Like Comment'),
    ]
    
    STATUS_CHOICES = [
        (0, 'Unread'),
        (1, 'Read'),
    ]
    
    message_id = models.AutoField(primary_key=True, verbose_name='Message ID')
    received_user_id = models.CharField(max_length=15, blank=True, null=True, verbose_name='Received User ID')
    article_id = models.CharField(max_length=15, blank=True, null=True, verbose_name='Article ID')
    article_title = models.CharField(max_length=150, blank=True, null=True, verbose_name='Article Title')
    comment_id = models.IntegerField(blank=True, null=True, verbose_name='Comment ID')
    send_user_id = models.CharField(max_length=15, blank=True, null=True, verbose_name='Send User ID')
    send_nick_name = models.CharField(max_length=20, blank=True, null=True, verbose_name='Send Nickname')
    message_type = models.IntegerField(choices=MESSAGE_TYPE_CHOICES, blank=True, null=True, verbose_name='Message Type')
    message_content = models.CharField(max_length=1000, blank=True, null=True, verbose_name='Message Content')
    status = models.IntegerField(choices=STATUS_CHOICES, default=0, verbose_name='Status')
    create_time = models.DateTimeField(default=timezone.now, verbose_name='Create Time')
    
    class Meta:
        db_table = 'user_message'
        verbose_name = 'User Message'
        verbose_name_plural = 'User Messages'
        indexes = [
            models.Index(fields=['received_user_id']),
            models.Index(fields=['status']),
            models.Index(fields=['message_type']),
        ]
        unique_together = ['article_id', 'comment_id', 'send_user_id', 'message_type']


class SysInfo(models.Model):
    """系统信息模型"""
    sys_id = models.CharField(max_length=10, primary_key=True, verbose_name='System ID')
    content = models.CharField(max_length=500, blank=True, null=True, verbose_name='Content')
    
    class Meta:
        db_table = 'sys_info'
        verbose_name = 'System Info'
        verbose_name_plural = 'System Info'

    def __str__(self):
        return self.sys_id


class PendingUserRegistration(models.Model):
    """外来用户注册申请模型"""
    STATUS_CHOICES = [
        (0, 'Pending'),
        (1, 'Approved'),
        (2, 'Rejected'),
    ]
    
    id = models.AutoField(primary_key=True, verbose_name='Application ID')
    email = models.EmailField(max_length=100, verbose_name='Email')
    nickname = models.CharField(max_length=50, verbose_name='Nickname')
    password = models.CharField(max_length=128, verbose_name='Password')
    institution = models.CharField(max_length=200, verbose_name='Institution Name')
    support = models.CharField(max_length=500, verbose_name='Support Document')
    status = models.IntegerField(choices=STATUS_CHOICES, default=0, verbose_name='Status')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Application Time')
    reviewed_at = models.DateTimeField(blank=True, null=True, verbose_name='Review Time')
    reviewed_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='reviewed_registrations',
        verbose_name='Reviewed By'
    )
    reject_reason = models.CharField(max_length=200, blank=True, null=True, verbose_name='Reject Reason')
    
    class Meta:
        db_table = 'pending_user_registrations'
        verbose_name = 'Pending User Registration'
        verbose_name_plural = 'Pending User Registrations'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['email']),
            models.Index(fields=['status']),
            models.Index(fields=['created_at']),
        ]
        
    def __str__(self):
        return f"{self.nickname} ({self.email}) - {self.get_status_display()}"
    
    def approve(self, reviewer):
        """批准注册申请"""
        from django.contrib.auth.hashers import make_password
        from utils.email_utils import send_registration_approval_email
        import logging
        
        logger = logging.getLogger(__name__)
        
        # 创建用户
        user = User.objects.create_user(
            email=self.email,
            nickname=self.nickname,
            password=None,
            institution=self.institution
        )
        user.password = self.password  # 使用申请时的加密密码
        user.save()
        
        # 更新申请状态
        self.status = 1
        self.reviewed_at = timezone.now()
        self.reviewed_by = reviewer
        self.save()
        
        # 发送申请通过通知邮件
        try:
            email_sent = send_registration_approval_email(self.email, self.nickname)
            if email_sent:
                logger.info(f"Registration approval email sent successfully to {self.email}")
            else:
                logger.warning(f"Failed to send registration approval email to {self.email}")
        except Exception as e:
            logger.error(f"Error sending registration approval email to {self.email}: {e}")
        
        return user
    
    def reject(self, reviewer, reason=None):
        """拒绝注册申请"""
        self.status = 2
        self.reviewed_at = timezone.now()
        self.reviewed_by = reviewer
        if reason:
            self.reject_reason = reason
        self.save()


class TopPostPermission(models.Model):
    """置顶帖子权限模型"""
    id = models.AutoField(primary_key=True, verbose_name='Permission ID')
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        verbose_name='User'
    )
    is_active = models.BooleanField(default=True, verbose_name='Is Active')
    granted_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='granted_top_permissions',
        verbose_name='Granted By'
    )
    create_time = models.DateTimeField(default=timezone.now, verbose_name='Create Time')
    update_time = models.DateTimeField(auto_now=True, verbose_name='Update Time')
    description = models.CharField(max_length=200, blank=True, null=True, verbose_name='Permission Description')
    
    class Meta:
        db_table = 'top_post_permissions'
        verbose_name = 'Top Post Permission'
        verbose_name_plural = 'Top Post Permissions'
        indexes = [
            models.Index(fields=['user']),
            models.Index(fields=['is_active']),
        ]
        
    def __str__(self):
        return f"{self.user.nickname} - Top Post Permission"